# tell/console.py
#
# tell monitoring software

"""

    W E L C O M E  T O  T E L L !!!

    -=-

    (this code is best enjoyed on a wide screen)

"""

## tell imports

from tell import defines, O, get_kernel, j
from .errors import NoCommand, TryAgain, NoAttribute, LifeError
from .utils import touch, error, completer
from .defines import datefmt, BLUE, RED, GREEN, BLA, BOLD, YELLOW, ENDC
from .bot import Bot
from .event import Event

## basic imports

import readline
import logging
import time
import code
import sys
import os

## alias

j = os.path.join

## bot handling the console

class Console(Bot):

    """ the console bot doing the input/output. IRC and XMPP soon to follow. """

    completions = {}

    def __init__(self, *args, **kwargs):
        Bot.__init__(self, *args, **kwargs)
        
    def _raw(self, txt):
        """ output stuff on the screen. """
        try: sys.stdout.write(txt +"\n")
        except TypeError: sys.stdout.write(str(txt))

    def exit(self, *args, **kwargs):
        """ shutdown this bot. """
        self.stopped = True
        logging.warn("writing to history file")
        try: readline.write_history_file(self.hfile)
        except: error()

    def run(self):
        """ start this bot. this function does not return until KeyboardInterrupt """
        self.kernel.boot()
        self.otype = "bot"
        self.name = "console"
        self.cbtype = "RUN"
        self.server = self.kernel.host
        self.user = self.kernel.shelluser
        if self.kernel.run_args and not "start" in self.kernel.run_args: self.kernel.handle_args() ; return
        if not self.kernel.silent: print("commands are: %s\n" % ", ".join([x.name for x in self.kernel.get_reg("cmnd")]))
        try:
            readline.set_completer(completer)
            readline.parse_and_bind("tab: complete")
        except: logging.error("no readline")
        self.stopped = False
        self.save()
        basic_event = Event(bot=self, origin=self.kernel.shellid, channel="shell", cbtype="CONSOLE")
        while not self.stopped: 
            try: 
                intxt = input("%s -=- %s%s<%s " % (time.strftime(datefmt), BOLD, YELLOW, ENDC))
                if not intxt: continue
                if self.stopped: return
                event = Event(**basic_event)
                event.input = intxt
                event.otype = "event"
                event.prepare()
                e = self.kernel.put(event)
                e.wait()
            except TryAgain: continue
            except NoCommand as ex: self._raw("no %s command available\n" % str(ex))
            except (KeyboardInterrupt, EOFError): break
            except: error()

    def say(self, channel, txt, *args, **kwargs):
        self._raw("%s -=- %s%s>%s %s" % (time.strftime(datefmt), BOLD, RED, ENDC, txt))

